﻿package frEngine.postProcess.postEffect
{
    import __AS3__.vec.*;
    import baseEngine.basic.*;
    import baseEngine.core.*;
    import baseEngine.system.*;
    import flash.display3D.*;
    import flash.geom.*;
    import frEngine.core.*;
    import frEngine.postProcess.*;
    import frEngine.render.layer.*;
    import frEngine.shader.filters.fragmentFilters.*;

    public class PeSpaceWarp extends PostEffectBase
    {
        private var _pass:PostPass;
        private var _targetWarpBuffer:PostTextureBuffer;
        private var _spaceWarpFilter:SpaceWarpFilter;
        private var _maxWarpPixel:int = 30;
        private var _layersort:Layer3DSort;
        private var _hasUpload:Boolean = false;

        public function PeSpaceWarp(param1:PostProcess)
        {
            this._spaceWarpFilter = new SpaceWarpFilter();
            super(param1);
            this.init();
            return;
        }// end function

        private function init() : void
        {
            this._targetWarpBuffer = new PostTextureBuffer(2048, 1024);
            this._pass = new PostPass();
            this._pass.setFs1(this._targetWarpBuffer);
            this._pass.isWriteToScene = true;
            this._pass.materialParam.addFilte(this._spaceWarpFilter);
            return;
        }// end function

        override public function get hasUpload() : Boolean
        {
            if (!this._hasUpload && this._pass.material.materialParams.program)
            {
                this._hasUpload = this._pass.material.materialParams.program.instanceRegister.hasAssembler;
            }
            return this._hasUpload;
        }// end function

        override public function immediatelyToUpload(param1:Scene3D) : void
        {
            this._targetWarpBuffer.immediatelyUploadTexture(param1);
            this._pass.material.buildBytes();
            return;
        }// end function

        public function reUpload(param1:Scene3D) : void
        {
            this._targetWarpBuffer.reUpload(param1);
            return;
        }// end function

        override public function get type() : int
        {
            return EPostEffectType.PeSpaceWarp;
        }// end function

        private function get spaceWrapLayer() : Layer3DSort
        {
            var _loc_1:RenderList = null;
            if (!this._layersort)
            {
                _loc_1 = Global3D.scene.renderLayerList;
                this._layersort = _loc_1.layMap[Layer3DManager.warpLayer];
            }
            return this._layersort;
        }// end function

        override public function get renderListLen() : int
        {
            var _loc_1:* = this.spaceWrapLayer;
            if (_loc_1)
            {
                return this._layersort.list.length;
            }
            return 0;
        }// end function

        private function drawLayer(param1:Layer3DSort) : void
        {
            var _loc_4:int = 0;
            if (!param1)
            {
                return;
            }
            if (param1.isActive)
            {
                param1.sort();
            }
            var _loc_2:* = param1.list;
            var _loc_3:* = _loc_2.length;
            if (_loc_3 > 0)
            {
                _loc_4 = 0;
                while (_loc_4 < _loc_3)
                {
                    
                    _loc_2[_loc_4].draw(false);
                    _loc_4++;
                }
            }
            return;
        }// end function

        private function drawWarp() : void
        {
            var _loc_4:int = 0;
            var _loc_5:Mesh3D = null;
            var _loc_1:* = this.spaceWrapLayer;
            if (!_loc_1)
            {
                return;
            }
            if (_loc_1.isActive)
            {
                _loc_1.sort();
            }
            var _loc_2:* = _loc_1.list;
            var _loc_3:* = _loc_2.length;
            if (_loc_3 > 0)
            {
                _loc_4 = 0;
                while (_loc_4 < _loc_3)
                {
                    
                    _loc_5 = _loc_2[_loc_4];
                    if (_loc_5.material.materialParams.blendMode == EBlendType.BLEND_MASKED)
                    {
                        Global3D.scene.context.setStencilActions(Context3DTriangleFace.FRONT_AND_BACK, Context3DCompareMode.NOT_EQUAL, Context3DStencilAction.KEEP);
                        _loc_5.draw(false);
                        Global3D.scene.context.setStencilActions(Context3DTriangleFace.FRONT_AND_BACK, Context3DCompareMode.ALWAYS, Context3DStencilAction.KEEP);
                    }
                    else
                    {
                        _loc_5.draw(false);
                    }
                    _loc_4++;
                }
            }
            return;
        }// end function

        private function drawWarpLayer(param1:Context3D) : void
        {
            var _loc_2:Layer3DSort = null;
            var _loc_3:* = Global3D.scene.renderLayerList;
            _loc_2 = _loc_3.layMap[Layer3DManager.backGroudMaskLayer];
            Global3D.scene.context.setStencilReferenceValue(1);
            Global3D.scene.context.setStencilActions(Context3DTriangleFace.FRONT_AND_BACK, Context3DCompareMode.ALWAYS, Context3DStencilAction.SET);
            param1.setColorMask(false, false, false, false);
            this.drawLayer(_loc_2);
            param1.setColorMask(true, true, true, true);
            this.drawWarp();
            return;
        }// end function

        override public function draw(param1:Context3D) : void
        {
            if (!param1)
            {
                return;
            }
            var _loc_2:* = Global3D.scene.renderLayerList;
            param1.setScissorRectangle(null);
            param1.setRenderToTexture(this._targetWarpBuffer.buffer, true);
            param1.clear(0, 0, 0, 0);
            _process.renderDepth(_loc_2);
            param1.clear(0, 0, 0, 0, 1, 0, Context3DClearMask.COLOR);
            this.drawWarpLayer(param1);
            this._pass.drawGrid(param1);
            return;
        }// end function

        override public function resize(param1:Rectangle) : void
        {
            this._pass.ViewPortResize(param1);
            this.resetFilterConst(param1);
            return;
        }// end function

        override public function ResetInputAndOutput(param1:PostTextureBuffer, param2:PostTextureBuffer) : void
        {
            this._pass.setFs0(param1);
            this._pass.setOutput(param2);
            return;
        }// end function

        public function get maxWarpPixel() : int
        {
            return this._maxWarpPixel;
        }// end function

        public function set maxWarpPixel(param1:int) : void
        {
            this._maxWarpPixel = param1;
            this.resetFilterConst(Global3D.scene.viewPort);
            return;
        }// end function

        private function resetFilterConst(param1:Rectangle) : void
        {
            this._spaceWarpFilter.warpConst[0] = this._maxWarpPixel / 2048;
            this._spaceWarpFilter.warpConst[1] = this._maxWarpPixel / 1024;
            return;
        }// end function

    }
}
